//
//  HomeViewController.m
//  mUBB
//
//  Created by Cosmin Stirbu on 2/24/13.
//  Copyright (c) 2013 Cosmin Stirbu. All rights reserved.
//

#import "HomeViewController.h"
#import "Course.h"
#import "Room.h"
#import "LoadingMoreCell.h"
#import "CoursesManager.h"
#import "RoomsManager.h"
#import "Constants.h"
#import "UIViewAdditions.h"
#import "NSString+Empty.h"
#import "WSError.h"
#import "CourseDetailsViewController.h"
#import "RoomDetailsViewController.h"
#import "ZBarReaderView.h"

@interface HomeViewController ()

@end

@implementation HomeViewController

@synthesize searchBar, resultsTableView, segmentedControl;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
        _items = [ListWrapper new];
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    
    // Set up the UI
    searchBar.tintColor = [Utils colorWithHexString:[[ConfigurationManager instance] UIConfigValueForKey:@"navigation_bar_color"]];
    searchBar.placeholder = NSLocalizedString(@"SEARCH_BAR_COURSES_PLACEHOLDER", nil);
    [searchBar setScopeButtonTitles:[NSArray arrayWithObjects:NSLocalizedString(@"SEARCH_BAR_NAME_SCOPE", nil), NSLocalizedString(@"SEARCH_BAR_CODE_SCOPE", nil), NSLocalizedString(@"SEARCH_BAR_TEACHER_SCOPE", nil), nil]];
    [searchBar setShowsScopeBar:YES];
    [searchBar sizeToFit];
    resultsTableView.top = searchBar.bottom;
    

    self.navigationItem.titleView = segmentedControl;
    [segmentedControl setTitle:NSLocalizedString(@"SEGMENTED_CONTROL_COURSES", nil) forSegmentAtIndex:0];
    [segmentedControl setTitle:NSLocalizedString(@"SEGMENTED_CONTROL_ROOMS", nil) forSegmentAtIndex:1];

    
    _coursesFilter = FILTER_NAME;
    _isDisplayingCourses = YES;
    
}

#pragma mark - UI Interaction

- (IBAction)valueChangedOnSegmentedController:(id)sender {
    [searchBar setText:@""];
    [NSObject cancelPreviousPerformRequestsWithTarget:self];
    if (segmentedControl.selectedSegmentIndex == 1) {
        // Rooms
        [searchBar setPlaceholder:NSLocalizedString(@"SEARCH_BAR_ROOMS_PLACEHOLDER", nil)];
        if ([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeCamera]) {
            self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCamera target:self action:@selector(cameraButtonPressed:)];
        }
        _isDisplayingCourses = NO;
        [searchBar setShowsScopeBar:NO];
        [searchBar sizeToFit];
        resultsTableView.top = searchBar.bottom;
        resultsTableView.height += searchBar.height;
    } else {
        // Courses
        _isDisplayingCourses = YES;
        [searchBar setPlaceholder:NSLocalizedString(@"SEARCH_BAR_COURSES_PLACEHOLDER", nil)];
        self.navigationItem.rightBarButtonItem = nil;
        [searchBar setShowsScopeBar:YES];
        [searchBar sizeToFit];
        resultsTableView.top = searchBar.bottom;
        resultsTableView.height -= searchBar.height / 2;
    }
    [_items removeAllObjects];
    [resultsTableView reloadData];
}

- (void)cameraButtonPressed:(id)sender {
    // Read QR Code
    ZBarReaderViewController *qrReader=[ZBarReaderViewController new];
    qrReader.readerDelegate=self;
    qrReader.supportedOrientationsMask=ZBarOrientationMask(1);
    qrReader.showsZBarControls=YES;

    ZBarImageScanner *scanner=qrReader.scanner;
    [scanner setSymbology:ZBAR_I25 config:ZBAR_CFG_ENABLE to:0];
    qrReader.readerView.tracksSymbols=NO;
    [self.navigationController presentModalViewController:qrReader animated:YES];
}

#pragma mark - ZBar Delegate

-(void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    [picker dismissModalViewControllerAnimated:YES];
    id <NSFastEnumeration> results=[info objectForKey:ZBarReaderControllerResults];
    ZBarSymbol *symbol=nil;
    for(symbol in results)
        break;
    if ([Utils isNumber:symbol.data]) {
        Room *room = [Room new];
        room.roomId = [symbol.data integerValue];
        RoomDetailsViewController *roomDetails = [[RoomDetailsViewController alloc] initWithNibName:@"RoomDetailsViewController" room:room];
        [self.navigationController pushViewController:roomDetails animated:YES];
    } else {
        // Invalid content
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:NSLocalizedString(@"INVALID_ROOM_ID", nil) delegate:nil cancelButtonTitle:NSLocalizedString(@"ALERT_OK", nil) otherButtonTitles:nil];
        [alert show];
    }
}


#pragma mark - Search Bar Methods Delegate

-(BOOL)searchBarShouldBeginEditing:(UISearchBar *)aSearchBar {
    [aSearchBar setShowsCancelButton:YES animated:YES];
    return YES;
}

- (void)searchBarCancelButtonClicked:(UISearchBar *)aSearchBar {
    [aSearchBar setShowsCancelButton:NO animated:YES];
    [aSearchBar resignFirstResponder];
}

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
    [NSObject cancelPreviousPerformRequestsWithTarget:self];
    if ([searchText isEqualToString:@""]) {
        [_items removeAllObjects];
        [resultsTableView reloadData];
    } else {
        _isAppendingItems = NO;
        [self performSelector:@selector(getItems) withObject:nil afterDelay:0.2];
    }
}

- (void)searchBar:(UISearchBar *)aSearchBar selectedScopeButtonIndexDidChange:(NSInteger)selectedScope {
    switch (selectedScope) {
        case 0: {
            _coursesFilter = FILTER_NAME;
            break;
        }
        case 1: {
            _coursesFilter = FILTER_CODE;
            break;
        }
        case 2: {
            _coursesFilter = FILTER_TEACHER;
            break;
        }
        default:
            break;
    }
    if (![NSString isNullOrEmpty:searchBar.text]) {
        [self getItems];
    }
}

- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
    [self getItems];
}

#pragma mark - Table View Delegate Methods

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    [searchBar resignFirstResponder];
    [searchBar setShowsCancelButton:NO animated:YES];
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [tableView deselectRowAtIndexPath:indexPath animated:NO];
    [searchBar resignFirstResponder];
    [searchBar setShowsCancelButton:NO animated:YES];
    // Check If Courses
    if (_isDisplayingCourses) {
        Course *course = [_items.itemsList objectAtIndex:indexPath.row];
        CourseDetailsViewController *courseDetailsViewController = [[CourseDetailsViewController alloc] initWithNibName:@"CourseDetailsViewController" course:course];
        [self.navigationController pushViewController:courseDetailsViewController animated:YES];
    } else {
       // Rooms
        Room *room = [_items.itemsList objectAtIndex:indexPath.row];
        RoomDetailsViewController *roomDetails = [[RoomDetailsViewController alloc] initWithNibName:@"RoomDetailsViewController" room:room];
        [self.navigationController pushViewController:roomDetails animated:YES];
    }
}


- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.row == [_items.itemsList count] - 1 && _items.totalNumberOfItems > [_items.itemsList count] && !_isAppendingItems) {
        _isAppendingItems = YES;
        if (_isDisplayingCourses) {
            _lastTicket = [[CoursesManager instance] getCoursesByKeyword:searchBar.text filter:_coursesFilter take:10 skip:[_items.itemsList count] delegate:self];
            _lastTicket.info = searchBar.text;
        } else {
           _lastTicket =  [[RoomsManager instance] getRoomsByKeyword:searchBar.text take:10 skip:[_items.itemsList count] delegate:self];
            _lastTicket.info  = searchBar.text;
        }
    }
}

#pragma mark - Table View Data Source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if ([_items.itemsList count] < _items.totalNumberOfItems) {
        return [_items.itemsList count] + 1;
    } else {
        return [_items.itemsList count];
    }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = nil;
    // Check if we should display the loading more cell
    if (indexPath.row == [_items.itemsList count]) {
        cell = [tableView dequeueReusableCellWithIdentifier:@"LoadingMore"];
        if (cell == nil) {
            NSArray *array = [[NSBundle mainBundle] loadNibNamed:@"LoadingMoreCell" owner:self options:nil];
            cell = [array objectAtIndex:0];
        }
    } else {
        // Room / Course cell
        cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
        if (cell == nil) {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"Cell"];
        }
        if (_isDisplayingCourses) {
                // Set Course info
                Course *course = [_items.itemsList objectAtIndex:indexPath.row];
                cell.textLabel.text = course.courseName;
                cell.detailTextLabel.text = course.courseCode;
        } else {
            // Set Room info
            Room *room = [_items.itemsList objectAtIndex:indexPath.row];
            cell.textLabel.text = room.name;
            cell.detailTextLabel.text = room.building.name;
        }
    }
    return cell;
}

#pragma mark - Private methods

- (void)getItems {
    [_items removeAllObjects];
    
    if (_isDisplayingCourses) {
       _lastTicket = [[CoursesManager instance] getCoursesByKeyword:searchBar.text filter:_coursesFilter take:10 skip:0 delegate:self];
       _lastTicket.info = searchBar.text;
    } else {
        _lastTicket = [[RoomsManager instance] getRoomsByKeyword:searchBar.text take:10 skip:0 delegate:self];
        _lastTicket.info = searchBar.text;
    }
}

#pragma mark - Courses Delegate Method

- (void)didReceiveCoursesWithSuccess:(id)object forTicket:(Ticket *)ticket {
    if (!_isOnScreen || !_isDisplayingCourses)
        return;
    ListWrapper *list = object;
    _items.totalNumberOfItems = list.totalNumberOfItems;
    if (_isAppendingItems && [ticket.info isEqualToString:searchBar.text]) {
            [_items.itemsList addObjectsFromArray:list.itemsList];
    } else if (!_isAppendingItems && _lastReceivedTicket.ticketId < ticket.ticketId) {
            [_items.itemsList addObjectsFromArray:list.itemsList];
    }
    _lastReceivedTicket = ticket;
    _isAppendingItems = NO;
    [resultsTableView reloadData];
}

- (void)didReceiveCoursesWithFailure:(id)object forTicket:(Ticket *)ticket {
    if (!_isOnScreen)
        return;
    _isAppendingItems = NO;
    [resultsTableView reloadData];
    
    WSError *error = object;
    if (error.errorCode != StatusCodeNotFound && !_alertOnScreen) {
        [self displayAlertWithMessage:error.errorMessage];
    }
}


#pragma mark - Rooms Delegate Method

- (void)didReceiveRoomsWithSuccess:(id)object forTicket:(Ticket *)ticket {
    if (!_isOnScreen || _isDisplayingCourses)
        return;
    ListWrapper *list = object;
    _items.totalNumberOfItems = list.totalNumberOfItems;
    if (_isAppendingItems && [ticket.info isEqualToString:searchBar.text]) {
        [_items.itemsList addObjectsFromArray:list.itemsList];
    } else if (!_isAppendingItems && _lastReceivedTicket.ticketId < ticket.ticketId) {
        [_items.itemsList addObjectsFromArray:list.itemsList];
    }
    _lastReceivedTicket = ticket;
    _isAppendingItems = NO;
    [resultsTableView reloadData];
}

- (void)didReceiveRoomsWithFailure:(id)object forTicket:(Ticket *)ticket {
    if (!_isOnScreen)
        return;
    _isAppendingItems = NO;
    [resultsTableView reloadData];
    WSError *error = object;
    
    if (error.errorCode != StatusCodeNotFound && !_alertOnScreen) {
        [self displayAlertWithMessage:error.errorMessage];
    }
}

- (void)displayAlertWithMessage:(NSString *)errorMessage {
    _alertOnScreen = YES;
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:errorMessage delegate:self cancelButtonTitle:NSLocalizedString(@"ALERT_CANCEL", nil) otherButtonTitles:NSLocalizedString(@"ALERT_RETRY", nil), nil];
    alertView.delegate = self;
    [alertView show];
}


#pragma mark - Alert View Delegate Method

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    _alertOnScreen = NO;
    if (alertView.cancelButtonIndex != buttonIndex) {
        [self getItems];
    }
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)viewDidUnload {
    [self setSearchBar:nil];
    [self setResultsTableView:nil];
    [self setSegmentedControl:nil];
    [super viewDidUnload];
}
@end
